//@author A0100965J
package gui;

import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import common.CommandType;

public class AutoComplete {

	private JTextField cmdLine;

	private static final String KEYWORD_NAME = "-name";
	private static final String KEYWORD_DESCRIPTION = "-description";
	private static final String KEYWORD_FROM = "-from";
	private static final String KEYWORD_TO = "-to";
	private static final String KEYWORD_DUE = "-due";
	private static final String KEYWORD_ID = "-id";
	private static final String KEYWORD_STATUS = "-status";
	private static final int EXCLUDE_PREFIX = 1;

	public AutoComplete(JTextField cmdLine) {
		this.cmdLine = cmdLine;
		String[] words = cmdLine.getText().trim().split(" ");
		String commandWord = words[0];
		CommandType type = determindCommandType(commandWord);
		if (type != null) {
			showAutoComplete(type);
		}
	}

	/**
	 * Auto-complete the keywords for different command types
	 * 
	 * @param type
	 *            The type of command, e.g. add, delete
	 */
	private void showAutoComplete(CommandType type) {
		String cmd = cmdLine.getText();
		String completion = "";
		int cursor = cmdLine.getCaretPosition();

		switch (type) {
		case add:
		case block:
			if (!cmd.contains(KEYWORD_NAME)) {
				completion = KEYWORD_NAME.substring(EXCLUDE_PREFIX);
			} else if (!cmd.contains(KEYWORD_DESCRIPTION) && !cmd.contains(KEYWORD_FROM)) {
				completion = KEYWORD_DESCRIPTION.substring(EXCLUDE_PREFIX);
			} else {
				if (!cmd.contains(KEYWORD_DUE) && !cmd.contains(KEYWORD_FROM) && !cmd.contains(KEYWORD_TO)) {
					completion = KEYWORD_DUE.substring(EXCLUDE_PREFIX);
				}
				if (cmd.contains(KEYWORD_FROM) && !cmd.contains(KEYWORD_TO) && !cmd.contains(KEYWORD_DUE)) {
					completion = KEYWORD_TO.substring(EXCLUDE_PREFIX);
				}
			}
			break;

		case update:
		case delete:
		case mark:
		case unmark:
		case discard:
		case unblock:
			if (!cmd.contains(KEYWORD_NAME)) {
				completion = KEYWORD_NAME.substring(EXCLUDE_PREFIX);
			}
			break;

		case confirm:
			if (!cmd.contains(KEYWORD_ID)) {
				completion = KEYWORD_ID.substring(EXCLUDE_PREFIX);
			}
			break;

		case display:
			if (!cmd.contains(KEYWORD_STATUS)) {
				completion = KEYWORD_STATUS.substring(EXCLUDE_PREFIX);
			}
			break;

		default:
			break;
		}
		SwingUtilities.invokeLater(new CompletionTask(completion, cursor));
	}

	/**
	 * Complete the keyword
	 */
	public void insertAutoCompletion() {
		int position = cmdLine.getSelectionEnd();
		StringBuilder cmd = new StringBuilder(cmdLine.getText());
		cmd.insert(position, " ");
		cmdLine.setText(cmd.toString());
		cmdLine.setCaretPosition(position + 1);
	}

	/**
	 * Determine the type of command
	 * 
	 * @param commandWord
	 *            The first word in the command line
	 * @return the type of command or null if the command word is invalid
	 */
	private CommandType determindCommandType(String commandWord) {
		try {
			return CommandType.valueOf(commandWord);
		} catch (IllegalArgumentException e) {
			return null;
		}
	}

	/**
	 * A private class which execute the auto-completion action
	 */
	private class CompletionTask implements Runnable {
		private String completion;
		private int position;

		CompletionTask(String completion, int position) {
			this.completion = completion;
			this.position = position;
		}

		/**
		 * Insert the keyword in the position specified
		 */
		public void run() {
			StringBuilder cmd = new StringBuilder(cmdLine.getText());

			cmd.insert(position, completion);
			cmdLine.setText(cmd.toString());
			cmdLine.setCaretPosition(position + completion.length());
			cmdLine.moveCaretPosition(position);
		}

	}
}
